package com.irssproject.app.bean.clustering;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ClusterTree {


    private ClusterNode rootElement;
    
    public static ClusterTree segonArbre;
    public static boolean segonArbreCompletamentAbsorbit;
    /**
     * Default ctor.
     */
    public ClusterTree() {
        super();
    }
 
    /**
     * Return the root Node of the tree.
     * @return the root element.
     */
    public ClusterNode getRootElement() {
        return this.rootElement;
    }
 
    /**
     * Set the root Element for the tree.
     * @param rootElement the root element to set.
     */
    public void setRootElement(ClusterNode rootElement) {
        this.rootElement = rootElement;
    }
     
    /**
     * Returns the Tree<T> as a List of Node<T> objects. The elements of the
     * List are generated from a pre-order traversal of the tree.
     * @return a List<Node<T>>.
     */
    public List<ClusterNode> toList() {
        List<ClusterNode> list = new ArrayList<ClusterNode>();
        walk(rootElement, list);
        return list;
    }
     
    /**
     * Returns a String representation of the Tree. The elements are generated
     * from a pre-order traversal of the Tree.
     * @return the String representation of the Tree.
     */
    public String toString() {
        return toList().toString();
    }
     
    /**
     * Walks the Tree in pre-order style. This is a recursive method, and is
     * called from the toList() method with the root element as the first
     * argument. It appends to the second argument, which is passed by reference     * as it recurses down the tree.
     * @param element the starting element.
     * @param list the output of the walk.
     */
    private void walk(ClusterNode element, List<ClusterNode> list) {
        list.add(element);
        for (ClusterNode data : element.getChildren()) {
            walk(data, list);
        }
    }
    
    /**
     * Returns true if the tree contains a clusterNode
     * with the valor string
     * 
     * @return true if valor is in clusterTree, false otherwise.
     */
    public boolean containsClusterNode(String valor)
    {
    	return this.getRootElement().containsNodeWithValor(valor);
    }
    
    
    /**
     * Inserts the incoming clusterTree to 'this'
     * 
     * @param the clusterTree we want to merge to 'this'
     */

    public void fusionar(ClusterTree clusterTree2)
    {
	    ClusterNode nodeActual1 = this.getRootElement();
	    ClusterNode nodeActual2 = clusterTree2.getRootElement();
	    
	    if (nodeActual1.getValor().equals(nodeActual2.getValor()))
	    {
		    nodeActual1.addChildren(nodeActual2.getChildren());
		    this.setRootElement(nodeActual1);
		    
		    if (nodeActual2.getValor().equals(segonArbre.getRootElement().getValor()))
		    {
			    segonArbreCompletamentAbsorbit = true;
		    }
	    }
	    else
	    {	    
		    Iterator<ClusterNode> it1 = nodeActual1.getChildren().iterator();

		    while (it1.hasNext())
		    {
			    ClusterTree subArbre1 = new ClusterTree();
			    subArbre1.setRootElement(it1.next());
			    subArbre1.fusionar(clusterTree2);
			    
			    Iterator<ClusterNode> it2 = nodeActual2.getChildren().iterator();

			    while (it2.hasNext())
			    {
				    ClusterTree subArbre2 = new ClusterTree();
				    subArbre2.setRootElement(it2.next());

				    subArbre1.fusionar(subArbre2);
			    }
		    }
	    }
    }
    
    public static ClusterTree getSegonArbre() {
	return segonArbre;
}

    public static void setSegonArbre(ClusterTree segonArbre) {
	    ClusterTree.segonArbre = segonArbre;
    }

	public static boolean isSegonArbreCompletamentAbsorbit() 
    {
	    return segonArbreCompletamentAbsorbit;
    }

	public static void setSegonArbreCompletamentAbsorbit(boolean b) {
		segonArbreCompletamentAbsorbit = b;
	
	}
}
